﻿#include "GActivityChaosDragon.h"
#include "ServerModule/LogicActivityModule.h"
#include "Character/CreatureMgr.h"
#include "Character/monster/MonsterRefCfg.h"
#include "Common/TableData/MonsterMonsterCfg.h"
#include "Character/monster/Monster.h"
#include "Character/drop/Drop.h"
#include "Character/drop/DropMgr.h"
#include "Script/ScriptMgr.h"
#include "Chat/ChatManager.h"
#include "Character/HuoYueDuPart.h"

GActivityChaosDragon::GActivityChaosDragon()
{
	Clear();
}

GActivityChaosDragon::~GActivityChaosDragon()
{

}

void GActivityChaosDragon::Clear()
{
	m_sceneId = 0;
	m_bossId = 0;
	m_bossLv = 0;
	m_posX = 0;
	m_posY = 0;
	m_posZ = 0;
	m_bossObjId = 0;
	m_broadCastA = false;
	m_broadCastB = false;
	m_broadCastC = false;
	m_broadCastD = false;
	m_broadCastE = false;
	m_broadCastF = false;
	m_isWin = false;
}

void GActivityChaosDragon::Init(uint32_t activityId)
{
	GActivity::Init(activityId);

	//注锟斤拷锟铰硷拷
	//g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_UNDER_ATTACK, 0, 0, NULL);
	//g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_CREATURE_DEAD, 0, CREATURE_PLAYER, NULL);
	//g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_CREATURE_DEAD, 0, CREATURE_MONSTER, NULL);
	//g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_ENTER_SCENE, 0, CREATURE_PLAYER, NULL);
}

void GActivityChaosDragon::UnInit()
{
	Clear();
	g_GetEvent()->UnSubscribeAll(this);
}

void GActivityChaosDragon::InitChaosDragonParam(const ChaosDragonInfo& chaosDragonInfo)
{
	m_sceneId = chaosDragonInfo.mapid();
	m_bossId = chaosDragonInfo.bossid();
	m_bossLv = chaosDragonInfo.bosslv();
	m_posX = chaosDragonInfo.posx();
	m_posY = chaosDragonInfo.posy();
	m_posZ = chaosDragonInfo.posz();
}

void GActivityChaosDragon::OnActivityStart()
{
	g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_UNDER_ATTACK, 0, 0, NULL);
	g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_CREATURE_DEAD, 0, CREATURE_PLAYER, NULL);
	g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_CREATURE_DEAD, 0, CREATURE_MONSTER, NULL);
	g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), EVENT_ENTER_SCENE, 0, CREATURE_PLAYER, NULL);

	MonsterExtendInfo extendInfo;
	extendInfo.set_level(m_bossLv);
	Point3<float> pos;
	pos.x = m_posX;
	pos.y = m_posY;
	pos.z = m_posZ;
	Point3<float> dir = Point3<float>(0, 0, 1);
	MonsCreateParam createParam;
	createParam.createType = EMonsCreateType_Activity;
	createParam.createTypeVal = GetId();
	Monster* pMonster = g_GetCreatureMgr()->CreateMonster(m_bossId, m_sceneId, pos, createParam,dir, -1, &extendInfo);
	MMOLOG_FMT_DEBUG("GActivityChaosDragon::OnActivityStart monster:%d born x:%f, y:%f, z:%f, mapid:%d", m_bossId, pos.x, pos.y, pos.z, m_sceneId);
	if (nullptr != pMonster)
	{
		//锟斤拷锟斤拷锟斤拷锟街拷锟絙ossID
		m_bossObjId = pMonster->GetCid();

		Scene* pScene = pMonster->GetScene();
		if (nullptr != pScene)
		{
			int64_t curHp = pMonster->GetAttr(C_HP);
			int64_t maxHp = pMonster->GetAttr(C_MAX_HP);
			ActivityChaosDragonDropHpBocrast notify;
			notify.set_monsterid(m_bossId);
			notify.set_curhp(curHp);
			notify.set_maxhp(maxHp);
			pScene->BroadCast2ClientInScene(EMODULE_ID_ACTIVITY, LOGIC_TO_CLIENT_ACTIVITY_CHAODRAGON_DROPHP_BOCRAST, &notify);
		}
	}
}

void GActivityChaosDragon::OnActivityStop()
{
	//锟叫讹拷锟角凤拷锟斤拷锟斤拷锟斤拷BOSS锟斤拷要锟斤拷锟狡筹拷
	if (m_bossObjId > 0)
	{
		Monster* pBossMonster = g_GetCreatureMgr()->GetMonster(m_bossObjId);
		if (nullptr != pBossMonster)
		{
			if (pBossMonster->LeaveScene())
			{
				//pBossMonster->SetDestory();
				g_GetCreatureMgr()->Destory(m_bossObjId);
				m_bossObjId = 0;
			}
			//锟斤拷锟斤拷锟筋动锟斤拷锟斤拷
			ActivityStopEvent activityStop;
			activityStop.activityId = GetId();
			g_GetEvent()->FireExecute(EVENT_ACTIVITY_STOP, 0, 0, (ActivityStopEvent*)&activityStop, sizeof(ActivityStopEvent));
		}

		//失锟杰达拷锟斤拷
		SystemChatMsgData msgData;
		g_GetChatMgr()->SendG2WBroadcast(BT_ACTIVITY_CHAOS_DRAGON_FAIL, msgData);
	}

	//通知锟斤拷锟侥凤拷锟筋动锟斤拷锟斤拷
	CLStaticActivityClose req;
	req.set_activityid(GetId());
	req.set_iswin(m_isWin);
	g_GetLogicService()->SendDataToCenter(EMODULE_ID_ACTIVITY, LOGIC_TO_CENTER_STATIC_ACTIVITY_CLOSE, &req);

	//锟斤拷锟斤拷锟斤拷斜锟斤拷锟?
	Clear();

	g_GetEvent()->UnSubscribeAll(this);
}

void GActivityChaosDragon::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{
	switch (nEventID)
	{
	case EVENT_UNDER_ATTACK:
	{
		if (nLen != sizeof(skillAttackEvent))
		{
			LogErrFmtPrint("[logic] GActivityChaosDragon::OnExecute....nLen != sizeof(PickItemEvent)....len:%d ", nLen);
			return;
		}

		skillAttackEvent attackEvent = *(skillAttackEvent*)pContext;
		OnSkillAttack(attackEvent);
		break;
	}
	case EVENT_CREATURE_DEAD:
	{
		if (nLen != sizeof(DieEvent))
		{
			LogErrFmtPrint("[logic] GActivityWorldBoss::OnExecute....nLen != sizeof(DieEvent)....len:%d ", nLen);
			return;
		}

		DieEvent dieEvent = *(DieEvent*)pContext;
		OnCreatureDie(dieEvent);
		break;
	}
	case EVENT_ENTER_SCENE:
	{
		if (nLen != sizeof(EnterSceneEvent))
		{
			LogErrFmtPrint("[logic] GActivityWorldBoss::OnExecute nLen != sizeof(EnterSceneEvent)...len:%d", nLen);
			return;
		}
		EnterSceneEvent pEnter = *(EnterSceneEvent*)pContext;
		OnSceneEnter(pEnter);
		break;
	}
	default:
		break;
	}
}

bool GActivityChaosDragon::OnSkillAttack(skillAttackEvent& attackEvent)
{
	//锟斤拷锟斤拷锟斤拷锟矫伙拷锟斤拷锟斤拷冶锟斤拷锟斤拷锟斤拷锟斤拷腔锟斤拷锟街拷锟?
	if (m_bossObjId > 0 && attackEvent.victim == m_bossObjId)
	{
		Monster* pBossMonster = g_GetCreatureMgr()->GetMonster(m_bossObjId);
		if (nullptr != pBossMonster)
		{
			Participating(attackEvent.attacker);
			int64_t curHp = pBossMonster->GetAttr(C_HP);
			int64_t maxHp = pBossMonster->GetAttr(C_MAX_HP);
			curHp = curHp - attackEvent.sufferedValue < 0 ? 0 : curHp - attackEvent.sufferedValue;
			int64_t param = 0;
			if (curHp >= maxHp * 0.2)
			{
				if (curHp <= maxHp * 0.8 && !m_broadCastA)
				{
					param = 80;
					m_broadCastA = true;
				}

				else if (curHp <= maxHp * 0.6 && !m_broadCastB)
				{
					param = 60;
					m_broadCastB = true;
				}

				else if (curHp <= maxHp * 0.4 && !m_broadCastC)
				{
					param = 40;
					m_broadCastC = true;
				}

				if (param > 0)
				{
					SystemChatMsgData msgData;
					msgData.params.push_back(param);
					g_GetChatMgr()->SendG2WBroadcast(BT_ACTIVITY_CHAOS_DRAGON_DROP_HP_A, msgData);
				}
			}

			else if (curHp < maxHp * 0.2 && curHp > maxHp * 0.05)
			{
				if (curHp <= maxHp * 0.15 && !m_broadCastD)
				{
					param = 15;
					m_broadCastD = true;
				}

				else if (curHp <= maxHp * 0.1 && !m_broadCastE)
				{
					param = 10;
					m_broadCastE = true;
				}

		/*		else if (curHp <= maxHp * 0.05 && !m_broadCastF)
				{
					param = 5;
					m_broadCastF = true;
				}*/

				if (param > 0)
				{
					SystemChatMsgData msgData;
					msgData.params.push_back(param);
					g_GetChatMgr()->SendG2WBroadcast(BT_ACTIVITY_CHAOS_DRAGON_DROP_HP_B, msgData);
				}
			}
			else
			{
				if (curHp <= maxHp * 0.05 && !m_broadCastF)
				{
					param = 5;
					m_broadCastF = true;
				}

				if (param > 0)
				{
					SystemChatMsgData msgData;
					msgData.params.push_back(param);
					g_GetChatMgr()->SendG2WBroadcast(BT_ACTIVITY_CHAOS_DRAGON_DROP_HP_B, msgData);
				}
			}

			//锟姐播锟斤拷血
			Scene* pScene = pBossMonster->GetScene();
			if (nullptr != pScene)
			{
				ActivityChaosDragonDropHpBocrast notify;
				notify.set_monsterid(m_bossId);
				notify.set_curhp(curHp);
				notify.set_maxhp(maxHp);
				pScene->BroadCast2ClientInScene(EMODULE_ID_ACTIVITY, LOGIC_TO_CLIENT_ACTIVITY_CHAODRAGON_DROPHP_BOCRAST, &notify);
			}
		}

		//通知锟斤拷锟侥凤拷统锟狡伙拷杀锟斤拷锟斤拷息
		LCActivityMonsterAttackedReq attackedReq;
		attackedReq.set_activityid(GetId());
		attackedReq.set_charid(attackEvent.attacker);
		attackedReq.set_damageval(attackEvent.sufferedValue);
		g_GetLogicService()->SendDataToCenter(EMODULE_ID_ACTIVITY, LOGIC_TO_CENTER_ACTIVITY_MONSTER_ATTACKED, &attackedReq);

		if (m_joinList.count(attackEvent.attacker) <= 0)
		{
			Player *pPlayer = g_GetSceneMgr()->GetPlayer(m_sceneId, attackEvent.attacker);
			if (nullptr != pPlayer)
			{
				HuoYueDuPart *pPart = dynamic_cast<HuoYueDuPart*>(pPlayer->GetPart(PART_HUOYUEDU));
				if (nullptr != pPart)
				{
					pPart->AddHuoYueDuRecord(HYDT_ACTIVITY_CHAOS_DRAGON);
				}
			}
			m_joinList.insert(attackEvent.attacker);
		}
	}

	return true;
}

bool GActivityChaosDragon::OnCreatureDie(DieEvent& dieEvent)
{
	//锟斤拷锟斤拷芄锟斤拷锟斤拷锟斤拷腔锟斤拷锟街拷锟?
	if (dieEvent.nCid == m_bossObjId)
	{
		Player* pPlayer = g_GetCreatureMgr()->GetPlayer(dieEvent.killerCid);
		if (nullptr == pPlayer)
		{
			MMOLOG_FMT_ERROR("GActivityChaosDragon::OnMonsterDie but nullptr == pPlayer cid:%lu", dieEvent.killerCid);
			return false;
		}

		m_bossObjId = 0;

		SetWin(true);

		//锟斤拷锟叫达拷锟脚广播
		SystemChatMsgData msgData;
		CharacterPlayerMiniInfo playerInfo;
		g_GetChatMgr()->InitPlayerMiniInfoStruct(pPlayer, playerInfo);
		msgData.players.push_back(playerInfo);
		msgData.params.push_back(pPlayer->GetCampId());
		g_GetChatMgr()->SendG2WBroadcast(BT_ACTIVITY_CHAOS_DRAGON_KILLED, msgData);

		//通知锟斤拷锟侥凤拷锟斤拷锟斤拷锟斤拷锟斤拷
		LCActivityMonsterDieNotify notify;
		notify.set_activityid(GetId());
		notify.set_charid(dieEvent.killerCid);
		g_GetLogicService()->SendDataToCenter(EMODULE_ID_ACTIVITY, LOGIC_TO_CENTER_ACTIVITY_MONSTER_DIE, &notify);

		//锟斤拷锟斤拷锟斤拷锟斤拷锟酵斤拷锟斤拷锟剿活动
		StopActivity();

		Scene* pScene = pPlayer->GetScene();
		if (nullptr != pScene)
		{
			ActivityChaosDragonDropHpBocrast notify;
			notify.set_monsterid(m_bossId);
			notify.set_curhp(0);
			notify.set_maxhp(100);	//boss死亡 最大血量大于0即可
			pScene->BroadCast2ClientInScene(EMODULE_ID_ACTIVITY, LOGIC_TO_CLIENT_ACTIVITY_CHAODRAGON_DROPHP_BOCRAST, &notify);
		}

		FinishActivity();
	}

	//锟斤拷锟斤拷锟缴憋拷锟斤拷腔锟斤拷锟街拷锟?
	if (dieEvent.killerCid == m_bossObjId)
	{
		Player* pPlayer = g_GetCreatureMgr()->GetPlayer(dieEvent.nCid);
		if (nullptr == pPlayer)
		{
			MMOLOG_FMT_ERROR("GActivityChaosDragon::OnPlayerDie but nullptr == pPlayer cid:%lu", dieEvent.nCid);
			return false;
		}

		//通知锟斤拷锟侥凤拷锟斤拷锟斤拷冶锟斤拷锟斤拷锟斤拷杀锟斤拷锟斤拷
		LCActivityPlayerDieNofity notify;
		notify.set_activityid(GetId());
		notify.set_charid(dieEvent.nCid);
		g_GetLogicService()->SendDataToCenter(EMODULE_ID_ACTIVITY, LOGIC_TO_CENTER_ACTIVITY_PLAYER_DIE, &notify);
	}

	return true;
}

bool GActivityChaosDragon::OnSceneEnter(EnterSceneEvent& enterSceneEvent)
{
	if (m_bossObjId > 0 && enterSceneEvent.mapId == m_sceneId)
	{
		Monster* pBossMonster = g_GetCreatureMgr()->GetMonster(m_bossObjId);
		if (nullptr != pBossMonster)
		{
			int64_t curHp = pBossMonster->GetAttr(C_HP);
			int64_t maxHp = pBossMonster->GetAttr(C_MAX_HP);

			Player* pPlayer = g_GetCreatureMgr()->GetPlayer(enterSceneEvent.cId);
			if (nullptr != pPlayer)
			{
				ActivityChaosDragonDropHpBocrast notify;
				notify.set_monsterid(m_bossId);
				notify.set_curhp(curHp);
				notify.set_maxhp(maxHp);
				pPlayer->SendDataToClientEx(EMODULE_ID_TASK, LOGIC_TO_CLIENT_ACTIVITY_CHAODRAGON_DROPHP_BOCRAST, &notify);
			}
		}
	}

	return true;
}

void GActivityChaosDragon::GetBossInfo(ActivitySonOfKillingTrackRsp &rsp)
{
	rsp.set_mapid(m_sceneId);
	rsp.set_read_pos(true);
	rsp.set_posx(m_posX);
	rsp.set_posy(m_posY);
	rsp.set_posz(m_posZ);
	rsp.set_bossid(m_bossId);
}